package com.cloud.custom.api.service.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloud.custom.api.bean.CustomCreateBean;
import com.cloud.custom.api.bean.CustomFormBean;
import com.cloud.custom.api.entity.CustomBizConfig;
import com.cloud.custom.api.entity.CustomBizFields;
import com.cloud.custom.api.mapper.CustomBizConfigMapper;
import com.cloud.custom.api.mapper.CustomBizFieldsMapper;
import com.cloud.custom.api.service.CustomBizService;
import com.cloud.custom.common.consts.CustomConsts;
import com.cloud.custom.common.context.HumanSession;
import com.cloud.custom.common.utils.SessionHelper;
import com.cloud.custom.workflow.command.WfResponse;
import com.cloud.custom.workflow.command.create.CreateCommand;
import com.cloud.custom.workflow.command.create.CreateRequest;
import com.cloud.custom.workflow.command.create.CreateResponse;
import com.cloud.custom.workflow.service.WorkflowCoreService;

import tk.mybatis.mapper.entity.Example;

@Transactional
@Service
public class CustomBizServiceImpl implements CustomBizService {

	@Autowired
	private CustomBizConfigMapper customBizConfigMapper;

	@Autowired
	private CustomBizFieldsMapper customBizFieldsMapper;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private WorkflowCoreService workflowCoreService;

	@Override
	public CustomCreateBean saveUpdateCustomBiz(CustomFormBean value) {
		CustomBizConfig config = customBizConfigMapper.selectByPrimaryKey(value.getBizId());
		Example example = new Example(CustomBizFields.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("bizId", value.getBizId());
		example.orderBy("displayOrder");
		List<CustomBizFields> fields = customBizFieldsMapper.selectByExample(example);
		// 循环赋值
		JSONArray array = JSON.parseArray(value.getFormValue());
		for (int i = 0; i < array.size(); i++) {
			JSONObject obj = (JSONObject) array.get(i);
			String name = obj.getString("name");
			if (!StringUtils.isEmpty(name)) {
				for (CustomBizFields field : fields) {
					if (name.equals(field.getDisplayName())) {
						String fieldValue = obj.getString("value");
						if (StringUtils.isEmpty(fieldValue)) {
							field.setValue(null);
						} else {
							field.setValue(fieldValue);
						}
						continue;
					}
				}
			}
		}
		if (null == value.getRecId() || 0 == value.getRecId()) {
			// 保存数据，启动工作流
			KeyHolder keyHolder = new GeneratedKeyHolder();
			jdbcTemplate.update(new PreparedStatementCreator() {
				@Override
				public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
					StringBuilder sqlBuilder = new StringBuilder();
					sqlBuilder.append("insert into ").append(config.getTableName()).append(
							" (rec_id, create_human_id, create_human_name, create_unit_id, create_unit_name, create_unit_code, create_time, state_id, state_name ");
					for (CustomBizFields field : fields) {
						sqlBuilder.append(", ").append(field.getColumnName());
					}
					sqlBuilder.append(") ");
					sqlBuilder.append("values (null, ?, ?, ?, ?, ?, ?, ?, ? ");
					for (int i = 0; i < fields.size(); i++) {
						sqlBuilder.append(", ").append("?");
					}
					sqlBuilder.append(")");
					PreparedStatement ps = con.prepareStatement(sqlBuilder.toString(), Statement.RETURN_GENERATED_KEYS);
					HumanSession session = SessionHelper.get();
					ps.setLong(1, session.getHumanId());
					ps.setString(2, session.getHumanName());
					ps.setLong(3, session.getUnitId());
					ps.setString(4, session.getUnitName());
					ps.setString(5, session.getUnitCode());
					ps.setTimestamp(6, new Timestamp(new Date().getTime()));
					ps.setInt(7, CustomConsts.REC_STATE_NORMAL);
					ps.setString(8, CustomConsts.REC_STATE_NAME_NORMAL);
					for (int i = 0; i < fields.size(); i++) {
						int paramIndex = 9 + i;
						CustomBizFields f = fields.get(i);
						ps.setObject(paramIndex, parseValueToObject(f, f.getColumnClassName()));
					}
					return ps;
				}

				// 利用FastJSON特性实现类型转换
				private Object parseValueToObject(CustomBizFields field, String fieldDataType) {
					JSONObject obj = (JSONObject) JSONObject.toJSON(field);
					try {
						return obj.getObject("value", Class.forName(fieldDataType));
					} catch (ClassNotFoundException e) {
						throw new RuntimeException(e);
					}
				}
			}, keyHolder);
			Long recId = keyHolder.getKey().longValue();
			// 启动工作流
			CustomCreateBean bean = new CustomCreateBean();
			bean.setBizId(value.getBizId());
			bean.setRecId(recId);
			if (null != config.getProcDefId() && config.getProcDefId() > 0) {
				WfResponse response = new CreateResponse();
				workflowCoreService.execute(new CreateRequest(config.getProcDefId(), recId), response,
						new CreateCommand());
				CreateResponse c = (CreateResponse) response;
				bean.setActDefId(c.getActDef().getActDefId());
				bean.setActId(c.getActId());
			}
			return bean;
		} else {
			// 更新数据
			jdbcTemplate.update(new PreparedStatementCreator() {
				@Override
				public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
					StringBuilder sqlBuilder = new StringBuilder("update ").append(config.getTableName())
							.append(" set ");
					boolean b = false;
					for (CustomBizFields field : fields) {
						if (b)
							sqlBuilder.append(", ");
						sqlBuilder.append(field.getColumnName()).append(" = ?");
						b = true;
					}
					sqlBuilder.append(" where rec_id = ?");
					PreparedStatement ps = con.prepareStatement(sqlBuilder.toString());
					int index = 1;
					for (CustomBizFields f : fields) {
						ps.setObject(index, parseValueToObject(f, f.getColumnClassName()));
						index++;
					}
					ps.setLong(index, value.getRecId());
					return ps;
				}

				private Object parseValueToObject(CustomBizFields field, String columnClassName) {
					JSONObject obj = (JSONObject) JSONObject.toJSON(field);
					try {
						return obj.getObject("value", Class.forName(columnClassName));
					} catch (ClassNotFoundException e) {
						throw new RuntimeException(e);
					}
				}
			});
			CustomCreateBean bean = new CustomCreateBean();
			bean.setRecId(value.getRecId());
			bean.setBizId(value.getBizId());
			return bean;
		}
	}

}
